﻿using Future.Common.Attribute;
using Future.Common.Const;
using Future.Common.Exception;
using Future.Common.Models;
using Future.Common.Utils;
using Future.IBLL;
using Future.IDAL;
using Future.Model.DtoModel;
using Future.Model.SysModel;
using Future.Model.ViewModel;

namespace Future.BLL
{
    /// <summary>
    /// 用户业务逻辑
    /// </summary>
    public class UserBLL : IUserBLL
    {
        private readonly IUserDAL _userDAL;
        private readonly IUserRoleDAL _userRoleDAL;
        private readonly IRoleDAL _roleDAL;
        private readonly IMenuDAL _menuDAL;

        public UserBLL(IUserDAL userDAL, IUserRoleDAL userRoleDAL, IRoleDAL roleDAL, IMenuDAL menuDAL)
        {
            _userDAL = userDAL;
            _userRoleDAL = userRoleDAL;
            _roleDAL = roleDAL;
            _menuDAL = menuDAL;
        }

        [Require]
        public bool AddInfo(UserInfoDto userDto)
        {
            UserModel existUser = _userDAL.Get(x => x.UserName == userDto.User.UserName);
            if (existUser != null)
            {
                throw new BusinessException("用户已经存在，添加失败！");
            }

            UserModel userModel = userDto.User;
            userModel.Id = Guid.NewGuid();
            userModel.Password = EncryptUtil.GetMD5(userModel.Password);
            _userDAL.Insert(userModel);
            GiveUserSetRole(userModel.Id, userDto.RoleIds);

            return true;
        }

        /// <summary>
        /// 设置用户角色
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="roleIds"></param>
        private void GiveUserSetRole(Guid userId, List<Guid> roleIds)
        {
            _userRoleDAL.Delete(x => x.UserId == userId);

            List<UserRoleModel> userRoleModels = new();
            foreach (Guid roleId in roleIds)
            {
                UserRoleModel userRoleModel = new()
                {
                    Id = Guid.NewGuid(),
                    UserId = userId,
                    RoleId = roleId
                };
                userRoleModels.Add(userRoleModel);
            }

            if (userRoleModels.Any())
            {
                _userRoleDAL.InsertMany(userRoleModels);
            }
        }

        public UserModel GetUser(string userName, string password)
        {
            password = EncryptUtil.GetMD5(password);
            UserModel user = _userDAL.Get(x => x.UserName == userName && x.Password == password);
            if (user == null)
            {
                throw new BusinessException("账号或密码错误");
            }

            if (!user.Status)
            {
                throw new BusinessException("账号已经停用");
            }

            return user;
        }

        public UserInfoVo GetUserAllInfo(Guid id)
        {
            UserModel userModel = _userDAL.Get(x => x.Id == id);
            List<RoleModel> roles = _roleDAL.GetRolesByUserId(id);
            List<string> permissionCodes = _menuDAL.GetMenusByUserId(id).Select(x => x.PermissionCode).Distinct().ToList();
            UserInfoVo userInfoVo = new()
            {
                UserBaseInfo = userModel,
                Roles = roles,
                RoleCodes = roles.Select(x => x.RoleCode).Distinct().ToList(),
                PermissionCodes = permissionCodes
            };
            if (userModel.UserName == SystemConst.ADMIN)
            {
                userInfoVo.RoleCodes.Add(SystemConst.ADMIN);
                userInfoVo.PermissionCodes.Add(SystemConst.ADMINPERMISSIONCODE);
            }

            return userInfoVo;
        }

        public PageModel<UserModel> SelctPageList(UserQueryDto queryDto, PageParModel page)
        {
            PageModel<UserModel> result = _userDAL.GetUserPageList(queryDto, page);
            return result;
        }

        public UserInfoDto GetUserById(Guid id)
        {
            UserInfoDto userInfoDto = new();
            UserModel userModel = _userDAL.Get(x => x.Id == id);
            List<UserRoleModel> userRoleModels = _userRoleDAL.GetList(x => x.UserId == userModel.Id);
            userInfoDto.User = userModel;
            userInfoDto.RoleIds = userRoleModels.Select(x => x.RoleId).ToList();
            List<RoleModel> roles = _roleDAL.GetList(x => userInfoDto.RoleIds.Contains(x.Id));
            userInfoDto.Roles = roles;
            return userInfoDto;
        }

        [Require]
        public bool UpdateInfo(UserInfoDto userDto)
        {
            UserModel userModel = _userDAL.Get(x => x.Id == userDto.User.Id);
            if (userModel == null)
            {
                throw new BusinessException("更新的用户不存在");
            }

            userModel.NickName = userDto.User.NickName;
            userModel.AvatarFileId = userDto.User.AvatarFileId;
            userModel.Remark = userDto.User.Remark;
            userModel.Status = userDto.User.Status;
            _userDAL.Update(userModel);
            GiveUserSetRole(userModel.Id, userDto.RoleIds);
            return true;
        }

        [Require]
        public bool DeleteUserList(List<Guid> ids)
        {
            _userDAL.Delete(x => ids.Contains(x.Id));
            return _userRoleDAL.Delete(x => ids.Contains(x.UserId));
        }

        public UserInfoDto AuthRole(Guid id)
        {
            UserInfoDto userInfoDto = new();
            UserModel userModel = _userDAL.Get(x => x.Id == id);
            List<UserRoleModel> userRoleModels = _userRoleDAL.GetList(x => x.UserId == userModel.Id);
            userInfoDto.User = userModel;
            userInfoDto.RoleIds = userRoleModels.Select(x => x.RoleId).ToList();
            List<RoleModel> roles = _roleDAL.GetList(x => x.Status);
            userInfoDto.Roles = roles;
            return userInfoDto;
        }

        public bool UpdateAuthRole(Guid userId, List<Guid> roleIds)
        {
            GiveUserSetRole(userId, roleIds);
            return true;
        }

        public bool RestPassword(Guid id, string password)
        {
            UserModel userModel = _userDAL.Get(x => x.Id == id);
            if (userModel == null)
            {
                throw new BusinessException("用户不存在");
            }
            userModel.Password = EncryptUtil.GetMD5(password);
            return _userDAL.Update(userModel);
        }

        public PageModel<UserModel> AllocatedUserPageList(UserQueryDto userQueryDto, PageParModel page)
        {
            return _userDAL.AllocatedUserPageList(userQueryDto, page);
        }

        public PageModel<UserModel> UnallocatedPageList(UserQueryDto userQueryDto, PageParModel page)
        {
            return _userDAL.UnallocatedPageList(userQueryDto, page);
        }

        public bool UpdateStatus(Guid userId, bool status)
        {
            UserModel userModel = _userDAL.Get(x => x.Id == userId);
            if (userModel == null)
            {
                throw new BusinessException("用户不存在");
            }

            userModel.Status = status;
            return _userDAL.Update(userModel);
        }

        public bool UpdateUserProfile(UserModel userModel)
        {
            UserModel user = _userDAL.Get(x => x.Id == userModel.Id);
            if (user == null)
            {
                throw new BusinessException("用户不存在");
            }

            user.NickName = userModel.NickName;
            return _userDAL.Update(user);
        }

        public bool UpdatePassword(Guid id, UserResetPwdDto userResetPwdDto)
        {
            UserModel user = _userDAL.Get(x => x.Id == id);
            if (user == null)
            {
                throw new BusinessException("用户不存在");
            }

            if (user.Password != EncryptUtil.GetMD5(userResetPwdDto.OldPassword))
            {
                throw new BusinessException("旧密码错误");
            }

            user.Password = EncryptUtil.GetMD5(userResetPwdDto.NewPassword);
            return _userDAL.Update(user);
        }

        public bool UpdateUserAvatar(UserModel userModel)
        {
            UserModel user = _userDAL.Get(x => x.UserName == userModel.UserName);
            if (user == null)
            {
                throw new BusinessException("用户不存在");
            }

            user.AvatarFileId = userModel.AvatarFileId;
            return _userDAL.Update(user);
        }
    }
}